iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
Modern Web

什麼都略懂一點,生活更多彩一些。從web跑js出發到部屬heroku伺服器撈取API建構線上網站與LineBot系列 第 8

[day08][後端][學習] RESTful API?用五個常用API協定構成五芒星

  • 分享至 

  • xImage
  •  

同步發表到驢形筆記

GET、POST、PUT、PATCH和DELETE與RESTful API?

RESTful API簡單來說就是對協定的一種設計風格,可以用最簡單的理解就是。GET負責拿資料、POST和PUT負責新增資料、PATCH用來改資料然後DELETE用來刪資料這樣,可以參考這篇API 是什麼? RESTful API 又是什麼?來深入理解,但每個團隊都會有各自的設計風格,但大意上是不會差距太多的。通常不會出現什麼上一個GET用來取得資料下一個GET用來刪除資料之類的...

自動重啟伺服器!

到現在應該很常重啟伺服器吧,現在就讓我們來解決這個問題

只要借助nodemon來替換掉npm內的腳本命令就可以簡單的達成重啟

npm install --save-dev nodemon

等等!?什麼是dev?讓我們看向"package.json"

package.json

{
  "name": "ithome-30day",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "ejs": "~2.6.1",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "morgan": "~1.9.1",
    "node-sass-middleware": "0.11.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.4"
  }
}

有注意到"nodemon"被另外放置了嗎?簡單來說"--dev"的意思是,這個套件只在建立檔案和開發階段等時候使用。所以這邊放置的是伺服器"上線運行"時所不需要的套件

好的還是這隻檔案,讓我們更改npm的腳本"scripts"

略
  "scripts": {
    "start": "nodemon ./bin/www"
  },
略

這樣每次修改檔案伺服器就會自動重啟,接著開始實作其他三個類型的協定。基本上協定只是一種約定的溝通方式,你想怎麼建立都可以。所以下面會一口氣將程式碼全部列出,想一個一個練習的朋友請照著PATCH->PUT->DELETE的路線練習。先更改test.ejs檔的部分再去修改test.js的部分

開啟伺服器吧!Terminal輸入npm start後前往網站(http://localhost:3000/test)

views\test.ejs

<!DOCTYPE html>
<html>

<head>
  <title>測試頁面</title>
  <link rel='stylesheet' href='/stylesheets/style.css' />
</head>

<body>
  <h1>這是測試頁面</h1>
  <p>Welcome to 這是測試頁面</p>
  <button id="callGetApi">GET API</button>
  <button id="callGetApi2">GET API2</button>
  <br>
  <button id="callPostApi">POST API</button>
  <br>
  <button id="callPutApi">PUT API</button>
  <br>
  <button id="callPatchApi">PATCH API</button>
  <br>
  <button id="callDeleteApi">DELETE API</button>
  <br>
  <a href="./">前往首頁</a>
  <script>
略
    // ====================== put =====================
    document.getElementById('callPutApi').addEventListener('click', async function () {
      let result = await fetch('/test/put/12345678?id=helloworld', {
        method: 'put',
        body: JSON.stringify({
          id: 987654321
        }),
        headers: {
          'content-type': 'application/json'
        },
      }).then(res => {
        return res.text();
      })
      alert(result);
    })
    // ====================== put =====================
    
    // ====================== patch =====================
    document.getElementById('callPatchApi').addEventListener('click', async function () {
      let result = await fetch('/test/patch/12345678?id=helloworld', {
        method: 'patch', // 這是陷阱喔,請看下方~
        body: JSON.stringify({
          id: 987654321
        }),
        headers: {
          'content-type': 'application/json'
        },
      }).then(res => {
        return res.text();
      })
      alert(result);
    })
    // ====================== patch =====================

    // ====================== delete =====================
    document.getElementById('callDeleteApi').addEventListener('click', async function () {
      let result = await fetch('/test/delete/12345678?id=helloworld', {
        method: 'delete',
        body: JSON.stringify({
          id: 987654321
        }),
        headers: {
          'content-type': 'application/json'
        },
      }).then(res => {
        return res.text();
      })
      alert(result);
    })
        // ====================== delete =====================
  </script>
</body>
</html>

routes\test.js

略
// ====================== put =====================
router.put('/put/:id', function (req, res, next) {
  res.json({
    status: 'OK',
    value: 'hello put!建立好囉!',
    query: req.query,
    params: req.params,
    body: req.body
  });
});
// ====================== put =====================

// ====================== patch =====================
router.patch('/patch/:id', function (req, res, next) {
  res.json({
    status: 'OK',
    value: 'hello patch!建立好囉!',
    query: req.query,
    params: req.params,
    body: req.body
  });
});
// ====================== patch =====================

// ====================== delete =====================
router.delete('/delete/:id', function (req, res, next) {
  res.json({
    status: 'OK',
    value: 'hello delete!建立好囉!',
    query: req.query,
    params: req.params,
    body: req.body
  });
});
// ====================== delete =====================
module.exports = router;

看到這邊,如果你在patch的部分時遇到錯誤,並且你不覺得自己的程式碼有錯誤,那可能是因為patch有詭異的bug,在客戶端發出patch的fatch請求的時候method內的patch要大寫!請參照(https://stackoverflow.com/questions/34666680/fetch-patch-request-is-not-allowed )

全部練習完成後,應該就能理解RESTful API只是一個設計風格不遵守程式也會動。建議各位跟著一套風格走培養好習慣!現在繼續靠著前人的鐵人賽:從無到有打造 RESTful API service幫助你在走歪的道路上越走越遠!

githubday08

帶參數方法追加

上一篇沒有講到header帶參數的方法!這邊會使用patch方法做修改,基本上很簡單,上面的部分有辦法推測出來的話,下面的功能應該也能推測就出來!

views\test.ejs

    // ====================== patch =====================
    document.getElementById('callPatchApi').addEventListener('click', async function () {
      let result = await fetch('/test/patch/12345678?id=helloworld', {
        method: 'PATCH',
        body: JSON.stringify({
          id: 987654321
        }),
        headers: {
          'content-type': 'application/json',
          'dododo': 'gogogo'
        },
      }).then(res => {
        return res.text();
      })
      alert(result);
    })
    // ====================== patch =====================

routes\test.js

// ====================== patch =====================
router.patch('/patch/:id', function (req, res, next) {
  res.json({
    status: 'OK',
    value: 'hello patch!建立好囉!',
    query: req.query,
    params: req.params,
    body: req.body,
    header: req.headers.dododo
  });
});
// ====================== patch =====================

上一篇
[day07][後端][學習] API各種參數傳送與接收
下一篇
[day09][工具] 用NGROK讓本地伺服器連接到外網
系列文
什麼都略懂一點,生活更多彩一些。從web跑js出發到部屬heroku伺服器撈取API建構線上網站與LineBot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言